﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufItemDeclaration.h"
#include "GnufBase.h"

namespace gnuf {
    
    class Info;
    struct ToolDefinitionData;

    class GNUF_BASE_EXPORT ToolDefinition
    {
        CANNOT_COPY_OR_ASSIGN(ToolDefinition)
        DEFINE_CAST_BASE(ToolDefinition)
    protected:
        explicit ToolDefinition(const EItemType, const wchar_t *);
        virtual ~ToolDefinition();

    public:
        inline EItemType type() const { return m_type; }
        inline const std::wstring & key() const { return m_key; }

        virtual void onRefreshStatus() {}
        virtual void onRefreshData(const ToolDefinitionData &) {}

        template <class TDerivedToolDefinition>
        TDerivedToolDefinition * cast() {
            if (TDerivedToolDefinition::Type() == m_type) {
                return static_cast<TDerivedToolDefinition *>(this);
            }
            return nullptr;
        }

    private:
        const EItemType m_type;
        const std::wstring m_key;
    };
    
    class GNUF_BASE_EXPORT ToolDefinitionManager final
    {
    private:
        ToolDefinitionManager();
        ~ToolDefinitionManager();

    public:
        static ToolDefinitionManager * get();

        ToolDefinition * toolDefinitionBy(const std::wstring &) const;
        const std::list<ToolDefinition *> & toolDefinitions() const { return m_toolDefs; }
        std::list<ToolDefinition *> toolDefinitions() { return m_toolDefs; }
        
        void refreshStatus();

    private:
        friend class ToolDefinition;
        void add(ToolDefinition *);
        void remove(const ToolDefinition * const);

        std::list<ToolDefinition *> m_toolDefs;
    };
    
}
